﻿namespace MyCoreLib.Automation
{
    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;

    public static class OutputExtensions
    { 
        /// <summary>
        /// Errors the specified self.
        /// </summary>
        /// <param name="self">The self.</param>
        /// <param name="message">The message.</param>
        [DebuggerStepThrough]
        public static void Error(this IOutput self, StringBuilder message)
        {
            if(self == null){ return; }
            if(message == null){ return; }
            self.Error(message.ToString());                  
        }

        /// <summary>
        /// Writes an error message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The object to format.</param>
        [DebuggerStepThrough]
        public static void Error(this IOutput self, string format, object arg0)
        {
            if(self == null){ return; }
            try
            {
                self.Error(string.Format(format, arg0));            
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}. {2}", format, arg0, ex));
            }                
        }

        /// <summary>
        /// Writes an error message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">.Message format</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        [DebuggerStepThrough]
        public static void Error(this IOutput self, string format, object arg0, object arg1)
        {
            if(self == null){ return; }
            try
            {
                self.Error(string.Format(format, arg0, arg1));                   
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}. {3}", format, arg0, arg1, ex));
            }                   
        }

        /// <summary>
        /// Writes an error message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        /// <param name="arg2">The third object to format.</param>
        [DebuggerStepThrough]
        public static void Error(this IOutput self, string format, object arg0, object arg1, object arg2)
        {
            if(self == null){ return; }
            try
            {
                self.Error(string.Format(format, arg0, arg1, arg2));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}, arg2 = {3}. {4}", format, arg0, arg1, arg2, ex));
            }                
        }

        /// <summary>
        /// Writes an error message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format</param>
        /// <param name="args">An object array that contains zero or more objects to format.</param>
        [DebuggerStepThrough]
        public static void Error(this IOutput self, string format, params object[] args)
        {
            if(self == null){ return; }
            try
            {
                self.Error(string.Format(format, args));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                var argsString = 
                    String.Join(", ", (from a in args select Object.ReferenceEquals(a, null) ? "null" : a.ToString()));
                Trace.TraceError(string.Format("FormatException: Format = {0}, args = {1}. {2}", format, argsString, ex));
            }                 
        }

        
        /// <summary>
        /// Errors the specified self.
        /// </summary>
        /// <param name="self">The self.</param>
        /// <param name="message">The message.</param>
        [DebuggerStepThrough]
        public static void Warning(this IOutput self, StringBuilder message)
        {
            if(self == null){ return; }
            if(message == null){ return; }
            self.Warning(message.ToString());                  
        }

        /// <summary>
        /// Writes a warning message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The object to format.</param>
        [DebuggerStepThrough]
        public static void Warning(this IOutput self, string format, object arg0)
        {
            if(self == null){ return; }
            try
            {
                self.Warning(string.Format(format, arg0));            
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}. {2}", format, arg0, ex));
            }                
        }

        /// <summary>
        /// Writes a warning message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">.Message format</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        [DebuggerStepThrough]
        public static void Warning(this IOutput self, string format, object arg0, object arg1)
        {
            if(self == null){ return; }
            try
            {
                self.Warning(string.Format(format, arg0, arg1));                   
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}. {3}", format, arg0, arg1, ex));
            }                   
        }

        /// <summary>
        /// Writes a warning message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        /// <param name="arg2">The third object to format.</param>
        [DebuggerStepThrough]
        public static void Warning(this IOutput self, string format, object arg0, object arg1, object arg2)
        {
            if(self == null){ return; }
            try
            {
                self.Warning(string.Format(format, arg0, arg1, arg2));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}, arg2 = {3}. {4}", format, arg0, arg1, arg2, ex));
            }                
        }

        /// <summary>
        /// Writes a warning message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format</param>
        /// <param name="args">An object array that contains zero or more objects to format.</param>
        [DebuggerStepThrough]
        public static void Warning(this IOutput self, string format, params object[] args)
        {
            if(self == null){ return; }
            try
            {
                self.Warning(string.Format(format, args));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                var argsString = 
                    String.Join(", ", (from a in args select Object.ReferenceEquals(a, null) ? "null" : a.ToString()));
                Trace.TraceError(string.Format("FormatException: Format = {0}, args = {1}. {2}", format, argsString, ex));
            }                 
        }

        
        /// <summary>
        /// Errors the specified self.
        /// </summary>
        /// <param name="self">The self.</param>
        /// <param name="message">The message.</param>
        [DebuggerStepThrough]
        public static void Information(this IOutput self, StringBuilder message)
        {
            if(self == null){ return; }
            if(message == null){ return; }
            self.Information(message.ToString());                  
        }

        /// <summary>
        /// Writes an information message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The object to format.</param>
        [DebuggerStepThrough]
        public static void Information(this IOutput self, string format, object arg0)
        {
            if(self == null){ return; }
            try
            {
                self.Information(string.Format(format, arg0));            
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}. {2}", format, arg0, ex));
            }                
        }

        /// <summary>
        /// Writes an information message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">.Message format</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        [DebuggerStepThrough]
        public static void Information(this IOutput self, string format, object arg0, object arg1)
        {
            if(self == null){ return; }
            try
            {
                self.Information(string.Format(format, arg0, arg1));                   
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}. {3}", format, arg0, arg1, ex));
            }                   
        }

        /// <summary>
        /// Writes an information message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format.</param>
        /// <param name="arg0">The first object to format.</param>
        /// <param name="arg1">The second object to format.</param>
        /// <param name="arg2">The third object to format.</param>
        [DebuggerStepThrough]
        public static void Information(this IOutput self, string format, object arg0, object arg1, object arg2)
        {
            if(self == null){ return; }
            try
            {
                self.Information(string.Format(format, arg0, arg1, arg2));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                Trace.TraceError(string.Format("FormatException: Format = {0}, arg0 = {1}, arg1 = {2}, arg2 = {3}. {4}", format, arg0, arg1, arg2, ex));
            }                
        }

        /// <summary>
        /// Writes an information message to the associated listeners using the specified message.
        /// </summary>
        /// <param name="self">Output</param>
        /// <param name="format">Message format</param>
        /// <param name="args">An object array that contains zero or more objects to format.</param>
        [DebuggerStepThrough]
        public static void Information(this IOutput self, string format, params object[] args)
        {
            if(self == null){ return; }
            try
            {
                self.Information(string.Format(format, args));                
            }
            catch(FormatException ex)
            {
                self.Error("Internal error");
                var argsString = 
                    String.Join(", ", (from a in args select Object.ReferenceEquals(a, null) ? "null" : a.ToString()));
                Trace.TraceError(string.Format("FormatException: Format = {0}, args = {1}. {2}", format, argsString, ex));
            }                 
        }

                 
    }
}